﻿#include "Rpc.service.h"
#include "XyNet/Common/Cast.h"
#include "XyNet/Common/Exception.h"

using namespace XyNet;

namespace XyNet
{

shared_ptr<RpcError> RpcErrors::createError(int code)
{
	static const map<int, RpcError> _errors = {
		{ ExceedMaxMessagePacketSize, { ExceedMaxMessagePacketSize, "ExceedMaxMessagePacketSize", "达到最大消息包尺寸" } },
		{ FileTranslateError, { FileTranslateError, "FileTranslateError", "文件传输错误" } },
		{ InvalidArgument, { InvalidArgument, "InvalidArgument", "无效参数" } },
		{ InvalidMessage, { InvalidMessage, "InvalidMessage", "无效消息" } },
		{ LogicError, { LogicError, "LogicError", "逻辑错误（业务处理抛出的错误）" } },
		{ NotConnected, { NotConnected, "NotConnected", "无连接" } },
		{ NotError, { NotError, "NotError", "无错误" } },
		{ NotHeartBeat, { NotHeartBeat, "NotHeartBeat", "没有心跳包" } },
		{ ParseMessageFailed, { ParseMessageFailed, "ParseMessageFailed", "消息解析失败" } },
		{ ReachMaxConnections, { ReachMaxConnections, "ReachMaxConnections", "达到最大连接数" } },
		{ ServiceNotFound, { ServiceNotFound, "ServiceNotFound", "没有找到服务" } },
		{ SocketError, { SocketError, "SocketError", "套接字错误" } },
		{ Timeout, { Timeout, "Timeout", "超时" } },
		{ UnknownError, { UnknownError, "UnknownError", "未知错误" } },
	};

	auto iter = _errors.find(code);
	if (iter != _errors.end())
		return make_shared<RpcError>(iter->second);
	return make_shared<RpcError>(_errors.at(RpcErrors::UnknownError));
}

BaseService::SendErrorMethod::Argument::Argument()
	: RpcArgument(std::make_shared<Request>(), std::make_shared<Response>()) {}

shared_ptr<BaseService::SendErrorMethod::Controller> BaseService::SendErrorMethod::Argument::getController()
{
	return XYNET_POINTER_DOWNCAST<Controller>(_controller);
}

shared_ptr<const BaseService::SendErrorMethod::Request> BaseService::SendErrorMethod::Argument::getRequest() const
{
	return XYNET_POINTER_DOWNCAST<Request>(_request);
}

shared_ptr<BaseService::SendErrorMethod::Response> BaseService::SendErrorMethod::Argument::getResponse()
{
	return XYNET_POINTER_DOWNCAST<Response>(_response);
}

shared_ptr<RpcArgument> BaseService::SendErrorMethod::Argument::clone()
{
	XYNET_CHECK(!_controller);
	auto copy = std::make_shared<Argument>();
	copy->_request->CopyFrom(*_request);
	copy->_response->CopyFrom(*_response);
	return copy;
}

void BaseService::SendErrorMethod::Argument::initializeController(RpcSocketChannel* socketChannel)
{
	XYNET_CHECK(!_controller);
	_controller = std::make_shared<Controller>(socketChannel);
}

BaseService::SendErrorMethod::Callback::Callback(
	shared_ptr<RpcArgument> argument,
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
	: RpcCallback(argument)
	, _responseHandler(responseHandler), _exceptionHandler(exceptionHandler) {}

shared_ptr<RpcCallback> BaseService::SendErrorMethod::Callback::clone()
{
	return std::make_shared<Callback>(_argument->clone(), _responseHandler, _exceptionHandler);
}

void BaseService::SendErrorMethod::Callback::doResponseHandler()
{
	if (_responseHandler)
		_responseHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
}

void BaseService::SendErrorMethod::Callback::doExceptionHandler()
{
	if (_exceptionHandler)
		_exceptionHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
	else
		XYNET_HANDLE_EXCEPTION(Exception(_argument->getController()->getError()->getInfo()));
}

BaseService::SendErrorMethod::SendErrorMethod(shared_ptr<RpcChannel> channel)
	: RpcMethod("SendError", 0x5ED90F27, 0x7353EF39), _channel(channel), _argument(std::make_shared<Argument>()) {}

shared_ptr<BaseService::SendErrorMethod::Request> BaseService::SendErrorMethod::getRequest()
{
	return const_pointer_cast<Request>(
		XYNET_POINTER_DOWNCAST<Argument>(_argument)->getRequest());
}

void BaseService::SendErrorMethod::call(
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
{
	_channel->callMethod(this, std::make_shared<Callback>(_argument, responseHandler, exceptionHandler));
}

BaseService::SendHeartBeatMethod::Argument::Argument()
	: RpcArgument(std::make_shared<Request>(), std::make_shared<Response>()) {}

shared_ptr<BaseService::SendHeartBeatMethod::Controller> BaseService::SendHeartBeatMethod::Argument::getController()
{
	return XYNET_POINTER_DOWNCAST<Controller>(_controller);
}

shared_ptr<const BaseService::SendHeartBeatMethod::Request> BaseService::SendHeartBeatMethod::Argument::getRequest() const
{
	return XYNET_POINTER_DOWNCAST<Request>(_request);
}

shared_ptr<BaseService::SendHeartBeatMethod::Response> BaseService::SendHeartBeatMethod::Argument::getResponse()
{
	return XYNET_POINTER_DOWNCAST<Response>(_response);
}

shared_ptr<RpcArgument> BaseService::SendHeartBeatMethod::Argument::clone()
{
	XYNET_CHECK(!_controller);
	auto copy = std::make_shared<Argument>();
	copy->_request->CopyFrom(*_request);
	copy->_response->CopyFrom(*_response);
	return copy;
}

void BaseService::SendHeartBeatMethod::Argument::initializeController(RpcSocketChannel* socketChannel)
{
	XYNET_CHECK(!_controller);
	_controller = std::make_shared<Controller>(socketChannel);
}

BaseService::SendHeartBeatMethod::Callback::Callback(
	shared_ptr<RpcArgument> argument,
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
	: RpcCallback(argument)
	, _responseHandler(responseHandler), _exceptionHandler(exceptionHandler) {}

shared_ptr<RpcCallback> BaseService::SendHeartBeatMethod::Callback::clone()
{
	return std::make_shared<Callback>(_argument->clone(), _responseHandler, _exceptionHandler);
}

void BaseService::SendHeartBeatMethod::Callback::doResponseHandler()
{
	if (_responseHandler)
		_responseHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
}

void BaseService::SendHeartBeatMethod::Callback::doExceptionHandler()
{
	if (_exceptionHandler)
		_exceptionHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
	else
		XYNET_HANDLE_EXCEPTION(Exception(_argument->getController()->getError()->getInfo()));
}

BaseService::SendHeartBeatMethod::SendHeartBeatMethod(shared_ptr<RpcChannel> channel)
	: RpcMethod("SendHeartBeat", 0xFBCBDC1F, 0x7353EF39), _channel(channel), _argument(std::make_shared<Argument>()) {}

shared_ptr<BaseService::SendHeartBeatMethod::Request> BaseService::SendHeartBeatMethod::getRequest()
{
	return const_pointer_cast<Request>(
		XYNET_POINTER_DOWNCAST<Argument>(_argument)->getRequest());
}

void BaseService::SendHeartBeatMethod::call(
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
{
	_channel->callMethod(this, std::make_shared<Callback>(_argument, responseHandler, exceptionHandler));
}

BaseService::GetUtcTimeMethod::Argument::Argument()
	: RpcArgument(std::make_shared<Request>(), std::make_shared<Response>()) {}

shared_ptr<BaseService::GetUtcTimeMethod::Controller> BaseService::GetUtcTimeMethod::Argument::getController()
{
	return XYNET_POINTER_DOWNCAST<Controller>(_controller);
}

shared_ptr<const BaseService::GetUtcTimeMethod::Request> BaseService::GetUtcTimeMethod::Argument::getRequest() const
{
	return XYNET_POINTER_DOWNCAST<Request>(_request);
}

shared_ptr<BaseService::GetUtcTimeMethod::Response> BaseService::GetUtcTimeMethod::Argument::getResponse()
{
	return XYNET_POINTER_DOWNCAST<Response>(_response);
}

shared_ptr<RpcArgument> BaseService::GetUtcTimeMethod::Argument::clone()
{
	XYNET_CHECK(!_controller);
	auto copy = std::make_shared<Argument>();
	copy->_request->CopyFrom(*_request);
	copy->_response->CopyFrom(*_response);
	return copy;
}

void BaseService::GetUtcTimeMethod::Argument::initializeController(RpcSocketChannel* socketChannel)
{
	XYNET_CHECK(!_controller);
	_controller = std::make_shared<Controller>(socketChannel);
}

BaseService::GetUtcTimeMethod::Callback::Callback(
	shared_ptr<RpcArgument> argument,
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
	: RpcCallback(argument)
	, _responseHandler(responseHandler), _exceptionHandler(exceptionHandler) {}

shared_ptr<RpcCallback> BaseService::GetUtcTimeMethod::Callback::clone()
{
	return std::make_shared<Callback>(_argument->clone(), _responseHandler, _exceptionHandler);
}

void BaseService::GetUtcTimeMethod::Callback::doResponseHandler()
{
	if (_responseHandler)
		_responseHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
}

void BaseService::GetUtcTimeMethod::Callback::doExceptionHandler()
{
	if (_exceptionHandler)
		_exceptionHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
	else
		XYNET_HANDLE_EXCEPTION(Exception(_argument->getController()->getError()->getInfo()));
}

BaseService::GetUtcTimeMethod::GetUtcTimeMethod(shared_ptr<RpcChannel> channel)
	: RpcMethod("GetUtcTime", 0x13432C70, 0x7353EF39), _channel(channel), _argument(std::make_shared<Argument>()) {}

shared_ptr<BaseService::GetUtcTimeMethod::Request> BaseService::GetUtcTimeMethod::getRequest()
{
	return const_pointer_cast<Request>(
		XYNET_POINTER_DOWNCAST<Argument>(_argument)->getRequest());
}

void BaseService::GetUtcTimeMethod::call(
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
{
	_channel->callMethod(this, std::make_shared<Callback>(_argument, responseHandler, exceptionHandler));
}

BaseService::GetBrokerQueriesMethod::Argument::Argument()
	: RpcArgument(std::make_shared<Request>(), std::make_shared<Response>()) {}

shared_ptr<BaseService::GetBrokerQueriesMethod::Controller> BaseService::GetBrokerQueriesMethod::Argument::getController()
{
	return XYNET_POINTER_DOWNCAST<Controller>(_controller);
}

shared_ptr<const BaseService::GetBrokerQueriesMethod::Request> BaseService::GetBrokerQueriesMethod::Argument::getRequest() const
{
	return XYNET_POINTER_DOWNCAST<Request>(_request);
}

shared_ptr<BaseService::GetBrokerQueriesMethod::Response> BaseService::GetBrokerQueriesMethod::Argument::getResponse()
{
	return XYNET_POINTER_DOWNCAST<Response>(_response);
}

shared_ptr<RpcArgument> BaseService::GetBrokerQueriesMethod::Argument::clone()
{
	XYNET_CHECK(!_controller);
	auto copy = std::make_shared<Argument>();
	copy->_request->CopyFrom(*_request);
	copy->_response->CopyFrom(*_response);
	return copy;
}

void BaseService::GetBrokerQueriesMethod::Argument::initializeController(RpcSocketChannel* socketChannel)
{
	XYNET_CHECK(!_controller);
	_controller = std::make_shared<Controller>(socketChannel);
}

BaseService::GetBrokerQueriesMethod::Callback::Callback(
	shared_ptr<RpcArgument> argument,
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
	: RpcCallback(argument)
	, _responseHandler(responseHandler), _exceptionHandler(exceptionHandler) {}

shared_ptr<RpcCallback> BaseService::GetBrokerQueriesMethod::Callback::clone()
{
	return std::make_shared<Callback>(_argument->clone(), _responseHandler, _exceptionHandler);
}

void BaseService::GetBrokerQueriesMethod::Callback::doResponseHandler()
{
	if (_responseHandler)
		_responseHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
}

void BaseService::GetBrokerQueriesMethod::Callback::doExceptionHandler()
{
	if (_exceptionHandler)
		_exceptionHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
	else
		XYNET_HANDLE_EXCEPTION(Exception(_argument->getController()->getError()->getInfo()));
}

BaseService::GetBrokerQueriesMethod::GetBrokerQueriesMethod(shared_ptr<RpcChannel> channel)
	: RpcMethod("GetBrokerQueries", 0x88D76562, 0x7353EF39), _channel(channel), _argument(std::make_shared<Argument>()) {}

shared_ptr<BaseService::GetBrokerQueriesMethod::Request> BaseService::GetBrokerQueriesMethod::getRequest()
{
	return const_pointer_cast<Request>(
		XYNET_POINTER_DOWNCAST<Argument>(_argument)->getRequest());
}

void BaseService::GetBrokerQueriesMethod::call(
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
{
	_channel->callMethod(this, std::make_shared<Callback>(_argument, responseHandler, exceptionHandler));
}

BaseService::BaseService() : RpcService("BaseService", 0x7353EF39) {}

shared_ptr<RpcArgument> BaseService::createMethodArgument(int methodId) const
{
	switch (methodId)
	{
	case (int)0x5ED90F27:
		return std::make_shared<SendErrorMethod::Argument>();
	case (int)0xFBCBDC1F:
		return std::make_shared<SendHeartBeatMethod::Argument>();
	case (int)0x13432C70:
		return std::make_shared<GetUtcTimeMethod::Argument>();
	case (int)0x88D76562:
		return std::make_shared<GetBrokerQueriesMethod::Argument>();
	default:
		XYNET_CHECK(false);
		return nullptr;
	}
}

void BaseService::onMethod(int methodId, RpcArgument* argument)
{
	switch (methodId)
	{
	case (int)0x5ED90F27:
		onSendError(XYNET_DOWNCAST<SendErrorMethod::Argument*>(argument));
		break;
	case (int)0xFBCBDC1F:
		onSendHeartBeat(XYNET_DOWNCAST<SendHeartBeatMethod::Argument*>(argument));
		break;
	case (int)0x13432C70:
		onGetUtcTime(XYNET_DOWNCAST<GetUtcTimeMethod::Argument*>(argument));
		break;
	case (int)0x88D76562:
		onGetBrokerQueries(XYNET_DOWNCAST<GetBrokerQueriesMethod::Argument*>(argument));
		break;
	default:
		XYNET_CHECK(false);
	}
}

DownloadService::GetResourceInfoMethod::Argument::Argument()
	: RpcArgument(std::make_shared<Request>(), std::make_shared<Response>()) {}

shared_ptr<DownloadService::GetResourceInfoMethod::Controller> DownloadService::GetResourceInfoMethod::Argument::getController()
{
	return XYNET_POINTER_DOWNCAST<Controller>(_controller);
}

shared_ptr<const DownloadService::GetResourceInfoMethod::Request> DownloadService::GetResourceInfoMethod::Argument::getRequest() const
{
	return XYNET_POINTER_DOWNCAST<Request>(_request);
}

shared_ptr<DownloadService::GetResourceInfoMethod::Response> DownloadService::GetResourceInfoMethod::Argument::getResponse()
{
	return XYNET_POINTER_DOWNCAST<Response>(_response);
}

shared_ptr<RpcArgument> DownloadService::GetResourceInfoMethod::Argument::clone()
{
	XYNET_CHECK(!_controller);
	auto copy = std::make_shared<Argument>();
	copy->_request->CopyFrom(*_request);
	copy->_response->CopyFrom(*_response);
	return copy;
}

void DownloadService::GetResourceInfoMethod::Argument::initializeController(RpcSocketChannel* socketChannel)
{
	XYNET_CHECK(!_controller);
	_controller = std::make_shared<Controller>(socketChannel);
}

DownloadService::GetResourceInfoMethod::Callback::Callback(
	shared_ptr<RpcArgument> argument,
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
	: RpcCallback(argument)
	, _responseHandler(responseHandler), _exceptionHandler(exceptionHandler) {}

shared_ptr<RpcCallback> DownloadService::GetResourceInfoMethod::Callback::clone()
{
	return std::make_shared<Callback>(_argument->clone(), _responseHandler, _exceptionHandler);
}

void DownloadService::GetResourceInfoMethod::Callback::doResponseHandler()
{
	if (_responseHandler)
		_responseHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
}

void DownloadService::GetResourceInfoMethod::Callback::doExceptionHandler()
{
	if (_exceptionHandler)
		_exceptionHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
	else
		XYNET_HANDLE_EXCEPTION(Exception(_argument->getController()->getError()->getInfo()));
}

DownloadService::GetResourceInfoMethod::GetResourceInfoMethod(shared_ptr<RpcChannel> channel)
	: RpcMethod("GetResourceInfo", 0x9B947791, 0x78FF2E9D), _channel(channel), _argument(std::make_shared<Argument>()) {}

shared_ptr<DownloadService::GetResourceInfoMethod::Request> DownloadService::GetResourceInfoMethod::getRequest()
{
	return const_pointer_cast<Request>(
		XYNET_POINTER_DOWNCAST<Argument>(_argument)->getRequest());
}

void DownloadService::GetResourceInfoMethod::call(
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
{
	_channel->callMethod(this, std::make_shared<Callback>(_argument, responseHandler, exceptionHandler));
}

DownloadService::GetFileDataMethod::Argument::Argument()
	: RpcArgument(std::make_shared<Request>(), std::make_shared<Response>()) {}

shared_ptr<DownloadService::GetFileDataMethod::Controller> DownloadService::GetFileDataMethod::Argument::getController()
{
	return XYNET_POINTER_DOWNCAST<Controller>(_controller);
}

shared_ptr<const DownloadService::GetFileDataMethod::Request> DownloadService::GetFileDataMethod::Argument::getRequest() const
{
	return XYNET_POINTER_DOWNCAST<Request>(_request);
}

shared_ptr<DownloadService::GetFileDataMethod::Response> DownloadService::GetFileDataMethod::Argument::getResponse()
{
	return XYNET_POINTER_DOWNCAST<Response>(_response);
}

shared_ptr<RpcArgument> DownloadService::GetFileDataMethod::Argument::clone()
{
	XYNET_CHECK(!_controller);
	auto copy = std::make_shared<Argument>();
	copy->_request->CopyFrom(*_request);
	copy->_response->CopyFrom(*_response);
	return copy;
}

void DownloadService::GetFileDataMethod::Argument::initializeController(RpcSocketChannel* socketChannel)
{
	XYNET_CHECK(!_controller);
	_controller = std::make_shared<Controller>(socketChannel);
}

DownloadService::GetFileDataMethod::Callback::Callback(
	shared_ptr<RpcArgument> argument,
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
	: RpcCallback(argument)
	, _responseHandler(responseHandler), _exceptionHandler(exceptionHandler) {}

shared_ptr<RpcCallback> DownloadService::GetFileDataMethod::Callback::clone()
{
	return std::make_shared<Callback>(_argument->clone(), _responseHandler, _exceptionHandler);
}

void DownloadService::GetFileDataMethod::Callback::doResponseHandler()
{
	if (_responseHandler)
		_responseHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
}

void DownloadService::GetFileDataMethod::Callback::doExceptionHandler()
{
	if (_exceptionHandler)
		_exceptionHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
	else
		XYNET_HANDLE_EXCEPTION(Exception(_argument->getController()->getError()->getInfo()));
}

DownloadService::GetFileDataMethod::GetFileDataMethod(shared_ptr<RpcChannel> channel)
	: RpcMethod("GetFileData", 0x6C96C8FD, 0x78FF2E9D), _channel(channel), _argument(std::make_shared<Argument>()) {}

shared_ptr<DownloadService::GetFileDataMethod::Request> DownloadService::GetFileDataMethod::getRequest()
{
	return const_pointer_cast<Request>(
		XYNET_POINTER_DOWNCAST<Argument>(_argument)->getRequest());
}

void DownloadService::GetFileDataMethod::call(
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
{
	_channel->callMethod(this, std::make_shared<Callback>(_argument, responseHandler, exceptionHandler));
}

DownloadService::DownloadService() : RpcService("DownloadService", 0x78FF2E9D) {}

shared_ptr<RpcArgument> DownloadService::createMethodArgument(int methodId) const
{
	switch (methodId)
	{
	case (int)0x9B947791:
		return std::make_shared<GetResourceInfoMethod::Argument>();
	case (int)0x6C96C8FD:
		return std::make_shared<GetFileDataMethod::Argument>();
	default:
		XYNET_CHECK(false);
		return nullptr;
	}
}

void DownloadService::onMethod(int methodId, RpcArgument* argument)
{
	switch (methodId)
	{
	case (int)0x9B947791:
		onGetResourceInfo(XYNET_DOWNCAST<GetResourceInfoMethod::Argument*>(argument));
		break;
	case (int)0x6C96C8FD:
		onGetFileData(XYNET_DOWNCAST<GetFileDataMethod::Argument*>(argument));
		break;
	default:
		XYNET_CHECK(false);
	}
}

UploadService::CreateUploadTaskMethod::Argument::Argument()
	: RpcArgument(std::make_shared<Request>(), std::make_shared<Response>()) {}

shared_ptr<UploadService::CreateUploadTaskMethod::Controller> UploadService::CreateUploadTaskMethod::Argument::getController()
{
	return XYNET_POINTER_DOWNCAST<Controller>(_controller);
}

shared_ptr<const UploadService::CreateUploadTaskMethod::Request> UploadService::CreateUploadTaskMethod::Argument::getRequest() const
{
	return XYNET_POINTER_DOWNCAST<Request>(_request);
}

shared_ptr<UploadService::CreateUploadTaskMethod::Response> UploadService::CreateUploadTaskMethod::Argument::getResponse()
{
	return XYNET_POINTER_DOWNCAST<Response>(_response);
}

shared_ptr<RpcArgument> UploadService::CreateUploadTaskMethod::Argument::clone()
{
	XYNET_CHECK(!_controller);
	auto copy = std::make_shared<Argument>();
	copy->_request->CopyFrom(*_request);
	copy->_response->CopyFrom(*_response);
	return copy;
}

void UploadService::CreateUploadTaskMethod::Argument::initializeController(RpcSocketChannel* socketChannel)
{
	XYNET_CHECK(!_controller);
	_controller = std::make_shared<Controller>(socketChannel);
}

UploadService::CreateUploadTaskMethod::Callback::Callback(
	shared_ptr<RpcArgument> argument,
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
	: RpcCallback(argument)
	, _responseHandler(responseHandler), _exceptionHandler(exceptionHandler) {}

shared_ptr<RpcCallback> UploadService::CreateUploadTaskMethod::Callback::clone()
{
	return std::make_shared<Callback>(_argument->clone(), _responseHandler, _exceptionHandler);
}

void UploadService::CreateUploadTaskMethod::Callback::doResponseHandler()
{
	if (_responseHandler)
		_responseHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
}

void UploadService::CreateUploadTaskMethod::Callback::doExceptionHandler()
{
	if (_exceptionHandler)
		_exceptionHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
	else
		XYNET_HANDLE_EXCEPTION(Exception(_argument->getController()->getError()->getInfo()));
}

UploadService::CreateUploadTaskMethod::CreateUploadTaskMethod(shared_ptr<RpcChannel> channel)
	: RpcMethod("CreateUploadTask", 0x5AA135B1, 0x805F4CE9), _channel(channel), _argument(std::make_shared<Argument>()) {}

shared_ptr<UploadService::CreateUploadTaskMethod::Request> UploadService::CreateUploadTaskMethod::getRequest()
{
	return const_pointer_cast<Request>(
		XYNET_POINTER_DOWNCAST<Argument>(_argument)->getRequest());
}

void UploadService::CreateUploadTaskMethod::call(
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
{
	_channel->callMethod(this, std::make_shared<Callback>(_argument, responseHandler, exceptionHandler));
}

UploadService::GetUploadInfoMethod::Argument::Argument()
	: RpcArgument(std::make_shared<Request>(), std::make_shared<Response>()) {}

shared_ptr<UploadService::GetUploadInfoMethod::Controller> UploadService::GetUploadInfoMethod::Argument::getController()
{
	return XYNET_POINTER_DOWNCAST<Controller>(_controller);
}

shared_ptr<const UploadService::GetUploadInfoMethod::Request> UploadService::GetUploadInfoMethod::Argument::getRequest() const
{
	return XYNET_POINTER_DOWNCAST<Request>(_request);
}

shared_ptr<UploadService::GetUploadInfoMethod::Response> UploadService::GetUploadInfoMethod::Argument::getResponse()
{
	return XYNET_POINTER_DOWNCAST<Response>(_response);
}

shared_ptr<RpcArgument> UploadService::GetUploadInfoMethod::Argument::clone()
{
	XYNET_CHECK(!_controller);
	auto copy = std::make_shared<Argument>();
	copy->_request->CopyFrom(*_request);
	copy->_response->CopyFrom(*_response);
	return copy;
}

void UploadService::GetUploadInfoMethod::Argument::initializeController(RpcSocketChannel* socketChannel)
{
	XYNET_CHECK(!_controller);
	_controller = std::make_shared<Controller>(socketChannel);
}

UploadService::GetUploadInfoMethod::Callback::Callback(
	shared_ptr<RpcArgument> argument,
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
	: RpcCallback(argument)
	, _responseHandler(responseHandler), _exceptionHandler(exceptionHandler) {}

shared_ptr<RpcCallback> UploadService::GetUploadInfoMethod::Callback::clone()
{
	return std::make_shared<Callback>(_argument->clone(), _responseHandler, _exceptionHandler);
}

void UploadService::GetUploadInfoMethod::Callback::doResponseHandler()
{
	if (_responseHandler)
		_responseHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
}

void UploadService::GetUploadInfoMethod::Callback::doExceptionHandler()
{
	if (_exceptionHandler)
		_exceptionHandler(XYNET_DOWNCAST<Argument*>(_argument.get()));
	else
		XYNET_HANDLE_EXCEPTION(Exception(_argument->getController()->getError()->getInfo()));
}

UploadService::GetUploadInfoMethod::GetUploadInfoMethod(shared_ptr<RpcChannel> channel)
	: RpcMethod("GetUploadInfo", 0x3EA04181, 0x805F4CE9), _channel(channel), _argument(std::make_shared<Argument>()) {}

shared_ptr<UploadService::GetUploadInfoMethod::Request> UploadService::GetUploadInfoMethod::getRequest()
{
	return const_pointer_cast<Request>(
		XYNET_POINTER_DOWNCAST<Argument>(_argument)->getRequest());
}

void UploadService::GetUploadInfoMethod::call(
	const function<void(Argument*)>& responseHandler,
	const function<void(Argument*)>& exceptionHandler)
{
	_channel->callMethod(this, std::make_shared<Callback>(_argument, responseHandler, exceptionHandler));
}

UploadService::UploadService() : RpcService("UploadService", 0x805F4CE9) {}

shared_ptr<RpcArgument> UploadService::createMethodArgument(int methodId) const
{
	switch (methodId)
	{
	case (int)0x5AA135B1:
		return std::make_shared<CreateUploadTaskMethod::Argument>();
	case (int)0x3EA04181:
		return std::make_shared<GetUploadInfoMethod::Argument>();
	default:
		XYNET_CHECK(false);
		return nullptr;
	}
}

void UploadService::onMethod(int methodId, RpcArgument* argument)
{
	switch (methodId)
	{
	case (int)0x5AA135B1:
		onCreateUploadTask(XYNET_DOWNCAST<CreateUploadTaskMethod::Argument*>(argument));
		break;
	case (int)0x3EA04181:
		onGetUploadInfo(XYNET_DOWNCAST<GetUploadInfoMethod::Argument*>(argument));
		break;
	default:
		XYNET_CHECK(false);
	}
}

}
